/*
 * To change this template, choose Tools | Templates and open the template in
 * the editor.
 */
package LogParser;

import java.io.File;
import java.io.RandomAccessFile;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Иван
 */
public class Parser {

    private final static Pattern ENTRY_MSG_END = Pattern.compile("(.*?)\\Q]]></log4j:message>\\E");
    private final static Pattern ENTRY_MSG_BEGIN = Pattern.compile("\\Q<log4j:message><![CDATA[\\E(.*?)");  
    private final static Pattern MSG_PATTERN = Pattern.compile("^" + ENTRY_MSG_BEGIN.toString() + ENTRY_MSG_END.toString() + "$");
  
    private StringBuilder entry = null;
    private static RandomAccessFile file;
    private String fileName;
    private static long position;
    private String comm, tmp;
    private Matcher matcher;
    private boolean isBuild;
    private Stack<Long> positions = new Stack<Long>();
    private long oldPosition, newPosition;
    
    public Parser(String fN) throws Exception {  
        fileName = fN;
        file = new RandomAccessFile(new File(fN), "rw");     
        oldPosition = file.length();
        position = oldPosition;
        newPosition  =oldPosition;
        
        entry = new StringBuilder(0);
    }

    public String back() throws Exception { 
        entry= new StringBuilder(0);
        file  = new RandomAccessFile(fileName, "rw") ;
        isBuild = false;
        positions.clear();
        
        file.seek(oldPosition);
        if(oldPosition == newPosition){
            newPosition = file.length();
        }
       
      long posit= file.getFilePointer();
       
      positions.push(oldPosition);
        while(file.getFilePointer() < newPosition){
            
          
            file.readLine();
            
            position = file.getFilePointer();
            
            positions.push(position);
        }          
       positions.pop();
      
       
        while (!isBuild && (position != 0) && !positions.isEmpty()) {          
            position = positions.pop();
          
            file.seek(position);
            newPosition  = position;           

            tmp = file.readLine();
            
            matcher = MSG_PATTERN.matcher(tmp);
            if (matcher.matches()) {
                entry.append(tmp);
                isBuild = true;
               
                entry.append(position);
                
            } else {
                matcher = ENTRY_MSG_END.matcher(tmp);
                if (matcher.matches()) {
                    entry.append(tmp);
                   
                } else {
                    matcher = ENTRY_MSG_BEGIN.matcher(tmp);
                    if (matcher.matches()) {
                        entry.append(tmp);
                       
                         entry.append(position);
                        isBuild = true;
                    }
                }
            }

        }
    
        file.close();
        return entry.toString();
    }

    public String next() throws Exception {
        entry= new StringBuilder(0);
        file  = new RandomAccessFile(fileName, "rw") ;     
         
        isBuild = false;    
        
        file.seek(position);
 
        while (!isBuild && (file.getFilePointer()  < file.length()) && (oldPosition != position)) {
            if(position == newPosition){
                file.readLine();
            }
            tmp = file.readLine();
            position = file.getFilePointer();

            matcher = MSG_PATTERN.matcher(tmp);
            if (matcher.matches()) {
                entry.append(tmp);
                 entry.append(position);
                isBuild = true;
            } else {           
                matcher = ENTRY_MSG_BEGIN.matcher(tmp);
                if (matcher.matches()) {
                    entry.append(tmp);
                } else {
                    matcher = ENTRY_MSG_END.matcher(tmp);
                    if (matcher.matches()) {
                        entry.append(tmp);
                         entry.append(position);
                        isBuild = true;
                    }
                }
            }
        }
        
        file.close();
        return entry.toString();
    }
}
